package com.exam.admin.service.Impl;

import com.exam.FaceLogin.bean.Face;
import com.exam.admin.mapper.AdminMapper;
import com.exam.admin.service.AdminService;
import com.exam.entity.*;
import com.exam.entity.dto.LogTableDto;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Objects;

@Service
public class AdminServiceImpl implements AdminService {

    @Autowired
    private AdminMapper adminMapper;

    /**
     * 分页查询日志
     *
     * @param pageNum
     * @param pageSize
     * @return
     */
    @Override
    public ApiResult findAllLog(Integer pageNum, Integer pageSize) {
        Page<LogTableDto> page = null;
        PageHelper.startPage(pageNum, pageSize);

        page = adminMapper.findAllLog();

//        对OperateName 设置值
        for (LogTableDto logTableDto : page) {
            // logTableDto.getRequestParams().contains("/exit") && Objects.equals(logTableDto.getMethod(), "POST")
            if (logTableDto.getRequestParams().contains("/exams/login") && Objects.equals(logTableDto.getMethod(), "POST")) {
                logTableDto.setOperateName("登录上线");
            }
            if (logTableDto.getRequestParams().contains("/exit") && Objects.equals(logTableDto.getMethod(), "POST")) {
                logTableDto.setOperateName("登出下线");
            }
            if (Objects.equals(logTableDto.getRequestParams(), "//exams/register")) {
                logTableDto.setOperateName("注册操作");
            }
            if (Objects.equals(logTableDto.getRequestParams(), "//exams/forgotPwd")) {
                logTableDto.setOperateName("找回密码");
            }
            if (Objects.equals(logTableDto.getRequestParams(), "//studentPWD")) {
                logTableDto.setOperateName("修改密码");
            }
            if (logTableDto.getRequestParams().contains("//teacher") && Objects.equals(logTableDto.getMethod(), "DELETE")) {
                logTableDto.setOperateName("删除教师");
            }
            if (logTableDto.getRequestParams().contains("//paper") && Objects.equals(logTableDto.getMethod(), "GET")) {
                logTableDto.setOperateName("开始考试");
            }
            if (Objects.equals(logTableDto.getRequestParams(), "//score")) {
                logTableDto.setOperateName("考试结束");
            }
            if (logTableDto.getRequestParams().contains("//message") && Objects.equals(logTableDto.getMethod(), "POST")) {
                logTableDto.setOperateName("添加留言");
            }
            if (logTableDto.getRequestParams().contains("//replay") && Objects.equals(logTableDto.getMethod(), "POST")) {
                logTableDto.setOperateName("添加评论");
            }
            if (logTableDto.getRequestParams().contains("replayDelete")) {
                logTableDto.setOperateName("删除评论");
            }

            if (logTableDto.getRequestParams().contains("deleteMessage")) {
                logTableDto.setOperateName("删除留言");
            }
            if (Objects.equals(logTableDto.getRequestParams(), "//exam") && Objects.equals(logTableDto.getMethod(), "POST")) {
                logTableDto.setOperateName("添加试卷");
            }
            if (Objects.equals(logTableDto.getRequestParams(), "//exam") && Objects.equals(logTableDto.getMethod(), "DELETE")) {
                logTableDto.setOperateName("删除试卷");
            }
            if (Objects.equals(logTableDto.getRequestParams(), "//exam") && Objects.equals(logTableDto.getMethod(), "PUT")) {
                logTableDto.setOperateName("修改试卷");
            }

            if (logTableDto.getRequestParams().contains("MultiQuestion")) {
                logTableDto.setOperateName("添加选择题");
            }
            if (logTableDto.getRequestParams().contains("fillQuestion")) {
                logTableDto.setOperateName("添加填空题");
            }
            if (logTableDto.getRequestParams().contains("judgeQuestion")) {
                logTableDto.setOperateName("添加判断题");
            }

            if (logTableDto.getRequestParams().contains("/student/") && Objects.equals(logTableDto.getMethod(), "DELETE")) {
                logTableDto.setOperateName("删除学生信息");
            }

            if (logTableDto.getRequestParams().contains("/student") && Objects.equals(logTableDto.getMethod(), "PUT")) {
                logTableDto.setOperateName("修改学生信息");
            }

            if (logTableDto.getRequestParams().contains("/student") && Objects.equals(logTableDto.getMethod(), "POST")) {
                logTableDto.setOperateName("添加学生信息");
            }
            if (logTableDto.getRequestParams().contains("/teacher") && Objects.equals(logTableDto.getMethod(), "POST")) {
                logTableDto.setOperateName("添加教师信息");
            }
            if (logTableDto.getRequestParams().contains("/teacher") && Objects.equals(logTableDto.getMethod(), "PUT")) {
                logTableDto.setOperateName("修改教师信息");
            }
            if (logTableDto.getRequestParams().contains("/teacher/") && Objects.equals(logTableDto.getMethod(), "DELETE")) {
                logTableDto.setOperateName("删除教师信息");
            }

        }

        ApiResult apiResult = new ApiResult();
        apiResult.setCode(200);
        apiResult.setMessage("查询成功");
        apiResult.setTotal(page.getTotal());
        apiResult.setSize(page.getPageSize());
        apiResult.setCurrent(pageNum);
        apiResult.setData(page);
        return apiResult;
    }

    /**
     * 根据id 回显日志信息
     *
     * @param logId
     * @return
     */
    @Override
    public ApiResult findByIdLog(Integer logId) {

        LogTableDto logTableDto = adminMapper.findByIdLog(logId);

        //        对OperateName 设置值
        if (Objects.equals(logTableDto.getRequestParams(), "/exams/login")) {
            logTableDto.setOperateName("登录上线");
        }
        if (Objects.equals(logTableDto.getRequestParams(), "/exit")) {
            logTableDto.setOperateName("登出下线");
        }
        if (Objects.equals(logTableDto.getRequestParams(), "/exams/register")) {
            logTableDto.setOperateName("注册操作");
        }
        if (Objects.equals(logTableDto.getRequestParams(), "/exams/forgotPwd")) {
            logTableDto.setOperateName("找回密码");
        }
        if (Objects.equals(logTableDto.getRequestParams(), "/studentPWD")) {
            logTableDto.setOperateName("修改密码");
        }
        if (logTableDto.getRequestParams().contains("/teacher") && Objects.equals(logTableDto.getMethod(), "DELETE")) {
            logTableDto.setOperateName("删除教师");
        }
        if (logTableDto.getRequestParams().contains("/paper") && Objects.equals(logTableDto.getMethod(), "GET")) {
            logTableDto.setOperateName("开始考试");
        }
        if (Objects.equals(logTableDto.getRequestParams(), "/score")) {
            logTableDto.setOperateName("考试结束");
        }
        if (logTableDto.getRequestParams().contains("/message") && Objects.equals(logTableDto.getMethod(), "POST")) {
            logTableDto.setOperateName("添加留言");
        }
        if (logTableDto.getRequestParams().contains("/replay") && Objects.equals(logTableDto.getMethod(), "POST")) {
            logTableDto.setOperateName("添加评论");
        }
        if (logTableDto.getRequestParams().contains("replayDelete")) {
            logTableDto.setOperateName("删除评论");
        }

        if (logTableDto.getRequestParams().contains("deleteMessage")) {
            logTableDto.setOperateName("删除留言");
        }
        if (logTableDto.getRequestParams().contains("/exam") && Objects.equals(logTableDto.getMethod(), "POST")) {
            logTableDto.setOperateName("添加试卷");
        }
        if (logTableDto.getRequestParams().contains("/exam") && Objects.equals(logTableDto.getMethod(), "DELETE")) {
            logTableDto.setOperateName("删除试卷");
        }
        if (logTableDto.getRequestParams().contains("/exam") && Objects.equals(logTableDto.getMethod(), "PUT")) {
            logTableDto.setOperateName("修改试卷");
        }

        if (logTableDto.getRequestParams().contains("MultiQuestion")) {
            logTableDto.setOperateName("添加选择题");
        }
        if (logTableDto.getRequestParams().contains("fillQuestion")) {
            logTableDto.setOperateName("添加填空题");
        }
        if (logTableDto.getRequestParams().contains("judgeQuestion")) {
            logTableDto.setOperateName("添加判断题");
        }

        if (logTableDto.getRequestParams().contains("/student") && Objects.equals(logTableDto.getMethod(), "DELETE")) {
            logTableDto.setOperateName("删除学生信息");
        }

        if (logTableDto.getRequestParams().contains("/student") && Objects.equals(logTableDto.getMethod(), "PUT")) {
            logTableDto.setOperateName("修改学生信息");
        }

        if (logTableDto.getRequestParams().contains("/student") && Objects.equals(logTableDto.getMethod(), "POST")) {
            logTableDto.setOperateName("添加学生信息");
        }
        if (logTableDto.getRequestParams().contains("/teacher") && Objects.equals(logTableDto.getMethod(), "POST")) {
            logTableDto.setOperateName("添加教师信息");
        }
        if (logTableDto.getRequestParams().contains("/teacher") && Objects.equals(logTableDto.getMethod(), "PUT")) {
            logTableDto.setOperateName("修改教师信息");
        }


        ApiResult apiResult = new ApiResult();
        if (logTableDto != null) {
            apiResult.setCode(200);
            apiResult.setMessage("查询成功");
            apiResult.setData(logTableDto);
        } else {
            apiResult.setCode(506);
            apiResult.setMessage("查询失败");
        }

        return apiResult;
    }

    /**
     * 修改日志信息
     *
     * @param logTableDto
     * @return
     */
    @Transactional
    @Override
    public ApiResult updateMyLog(LogTableDto logTableDto) {

        int countDelete = adminMapper.deleteMyLog(logTableDto.getId());
        int countInsert = adminMapper.insertMyLog(logTableDto);

        ApiResult apiResult = new ApiResult();
        if (countInsert > 0 && countDelete > 0) {
            apiResult.setCode(200);
            apiResult.setMessage("修改成功");
        } else {
            apiResult.setCode(200);
            apiResult.setMessage("修改失败");
        }

        return apiResult;

    }

    /**
     * 根据id删除日志信息
     *
     * @param logId
     * @return
     */
    @Override
    public ApiResult deleteByIdMyLog(Integer logId) {

        int countDelete = adminMapper.deleteMyLog(logId);

        ApiResult apiResult = new ApiResult();
        if (countDelete > 0) {
            apiResult.setCode(200);
            apiResult.setMessage("删除成功");
        } else {
            apiResult.setCode(200);
            apiResult.setMessage("删除失败");
        }

        return apiResult;
    }

    /**
     * 根据id来查找管理员信息
     * @param adminId
     * @return
     */
    @Override
    public ApiResult adminById(Long adminId) {
        Admin admin = adminMapper.adminById(adminId);

        ApiResult apiResult = new ApiResult();
        if (admin != null) {
            apiResult.setCode(200);
            apiResult.setMessage("查询成功");
            apiResult.setData(admin);
        } else {
            // 抛出异常
            apiResult.setCode(506);
            apiResult.setMessage("查询失败");
        }

        return apiResult;
    }

    /**
     * 导出日志数据表
     *
     * @param response
     */
    @Override
    public void exportBusinessData(HttpServletResponse response) {

        // 1、查询数据库，获取日志数据 -- 获取最近30天的数据
        LocalDate dateBegin = LocalDate.now().minusDays(30);
        LocalDate dateEnd = LocalDate.now().minusDays(1);

        // 基于模板文件创建一个新的Excel文件
        try {
            InputStream in = this.getClass().getClassLoader().getResourceAsStream("template/日志模板文件.xlsx");

            XSSFWorkbook excel = new XSSFWorkbook(in);

            // 获取表格文件的Sheet页
            XSSFSheet sheet = excel.getSheet("Sheet1");

            sheet.getRow(1).getCell(1).setCellValue("时间：" + dateBegin + "到" + dateEnd);

            XSSFRow row = sheet.getRow(3);
            int count = 0;

            for (int i = 0; i < 30; i++) {
                LocalDate date = dateBegin.plusDays(i);
                LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);
                LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);

                String formattedMinTime = beginTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                String formattedMaxTime = endTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

                // 查询某一天的日志数据
                List<LogTableDto> logTableDtos = adminMapper.getMyLogData
                        (formattedMinTime, formattedMaxTime);

                for (LogTableDto logTableDto : logTableDtos) {
                    row = sheet.getRow(3 + count);

                    if (row == null) { //当row为空时，创建row
                        row = sheet.createRow(3 + count);
                    }

                    XSSFCell cell = row.getCell(1);
                    for (int j = 1; j <= 9; j++) {
                        cell = row.getCell(j);
                        if (cell == null) {
                            cell = row.createCell(j);
                        }

                        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

                        if (j == 1) cell.setCellValue(dateFormat.format(logTableDto.getTimestamp())); // 获取时间
                        if (j == 2) cell.setCellValue(logTableDto.getId()); // 获取日志id
                        if (j == 3) cell.setCellValue(logTableDto.getUserId()); // 获取用户id
                        if (j == 4) cell.setCellValue(logTableDto.getUserName()); // 获取用户名

                        if (Objects.equals(logTableDto.getRequestParams(), "/exams/login")) {
                            logTableDto.setOperateName("登录上线");
                        }
                        if (Objects.equals(logTableDto.getRequestParams(), "/exit")) {
                            logTableDto.setOperateName("登出下线");
                        }
                        if (Objects.equals(logTableDto.getRequestParams(), "/exams/register")) {
                            logTableDto.setOperateName("注册操作");
                        }
                        if (Objects.equals(logTableDto.getRequestParams(), "/exams/forgotPwd")) {
                            logTableDto.setOperateName("找回密码");
                        }
                        if (Objects.equals(logTableDto.getRequestParams(), "/studentPWD")) {
                            logTableDto.setOperateName("修改密码");
                        }
                        if (logTableDto.getRequestParams().contains("/teacher") && Objects.equals(logTableDto.getMethod(), "DELETE")) {
                            logTableDto.setOperateName("删除教师");
                        }
                        if (logTableDto.getRequestParams().contains("/paper") && Objects.equals(logTableDto.getMethod(), "GET")) {
                            logTableDto.setOperateName("开始考试");
                        }
                        if (Objects.equals(logTableDto.getRequestParams(), "/score")) {
                            logTableDto.setOperateName("考试结束");
                        }
                        if (logTableDto.getRequestParams().contains("/message") && Objects.equals(logTableDto.getMethod(), "POST")) {
                            logTableDto.setOperateName("添加留言");
                        }
                        if (logTableDto.getRequestParams().contains("/replay") && Objects.equals(logTableDto.getMethod(), "POST")) {
                            logTableDto.setOperateName("添加评论");
                        }
                        if (logTableDto.getRequestParams().contains("replayDelete")) {
                            logTableDto.setOperateName("删除评论");
                        }

                        if (logTableDto.getRequestParams().contains("deleteMessage")) {
                            logTableDto.setOperateName("删除留言");
                        }
                        if (logTableDto.getRequestParams().contains("/exam") && Objects.equals(logTableDto.getMethod(), "POST")) {
                            logTableDto.setOperateName("添加试卷");
                        }
                        if (logTableDto.getRequestParams().contains("/exam") && Objects.equals(logTableDto.getMethod(), "DELETE")) {
                            logTableDto.setOperateName("删除试卷");
                        }
                        if (logTableDto.getRequestParams().contains("/exam") && Objects.equals(logTableDto.getMethod(), "PUT")) {
                            logTableDto.setOperateName("修改试卷");
                        }

                        if (logTableDto.getRequestParams().contains("MultiQuestion")) {
                            logTableDto.setOperateName("添加选择题");
                        }
                        if (logTableDto.getRequestParams().contains("fillQuestion")) {
                            logTableDto.setOperateName("添加填空题");
                        }
                        if (logTableDto.getRequestParams().contains("judgeQuestion")) {
                            logTableDto.setOperateName("添加判断题");
                        }

                        if (logTableDto.getRequestParams().contains("/student") && Objects.equals(logTableDto.getMethod(), "DELETE")) {
                            logTableDto.setOperateName("删除学生信息");
                        }

                        if (logTableDto.getRequestParams().contains("/student") && Objects.equals(logTableDto.getMethod(), "PUT")) {
                            logTableDto.setOperateName("修改学生信息");
                        }

                        if (logTableDto.getRequestParams().contains("/student") && Objects.equals(logTableDto.getMethod(), "POST")) {
                            logTableDto.setOperateName("添加学生信息");
                        }
                        if (logTableDto.getRequestParams().contains("/teacher") && Objects.equals(logTableDto.getMethod(), "POST")) {
                            logTableDto.setOperateName("添加教师信息");
                        }
                        if (logTableDto.getRequestParams().contains("/teacher") && Objects.equals(logTableDto.getMethod(), "PUT")) {
                            logTableDto.setOperateName("修改教师信息");
                        }

                        if (j == 5) cell.setCellValue(logTableDto.getOperateName()); // 获取操作名称
                        if (j == 6) cell.setCellValue(logTableDto.getIpAddress()); // 获取ip地址
                        if (j == 7) cell.setCellValue(logTableDto.getUserAgent()); // 获取浏览器
                        if (j == 8) cell.setCellValue(logTableDto.getRequestParams()); // 获取请求路径
                        if (j == 9) cell.setCellValue(logTableDto.getMethod()); // 获取请求方式

                    }
                    count++;
                }
                // 3、通过输出流将Excel文件下载到客户端浏览器
            }
            ServletOutputStream out = response.getOutputStream();
            excel.write(out); // 将Excel文件写回到客户端浏览器，可以看到一个保存对话框

            // 设置响应头
            response.setContentType("application/octet-stream");

            // 关闭资源
            out.close();
            excel.close();

        } catch (IOException e) {
            throw new RuntimeException(e);
        }


    }

    /**
     * 创建管理员
     * @param face
     * @return
     */
    @Override
    public int insertAdmin(Face face) {

        Admin admin = new Admin();
        admin.setAdminId(System.currentTimeMillis());
        admin.setAdminName(face.getFaceName());
        admin.setRole("0");
        admin.setFaceId(face.getFid());
        admin.setPwd("zhui2023");

        return adminMapper.insertAdmin(admin);
    }

    /**
     * 删除人脸，删除管理员信息
     * @param fid
     */
    @Override
    public void deleteByFaceIdAdmin(Integer fid) {
        adminMapper.deleteByFaceIdAdmin(fid);
    }

    /**
     * 修改管理员信息
     * @param face
     */
    @Override
    public void updateAdmin(Face face) {
        adminMapper.updateAdmin(face.getFaceName(), face.getFid());
    }

    /**
     * 根据faceId查询管理员
     * @param fid
     * @return
     */
    @Override
    public Admin findByIdAdmin(Integer fid) {
        return adminMapper.findByIdAdmin(fid);
    }

    /**
     * 修改管理员信息
     * @param admin
     * @return
     */
    @Transactional
    @Override
    public ApiResult updateByIdAdmin(Admin admin) {

        Admin admin1 = adminMapper.adminById(admin.getAdminId());
        // 根据id删除管理员信息
        int countDelete = adminMapper.deleteByIdAdmin(admin.getAdminId());
        // 插入数据
        admin.setFaceId(admin1.getFaceId());
        int countInsert = adminMapper.insertAdmin(admin);
        // 返回数据
        ApiResult apiResult = new ApiResult();
        if (countDelete > 0 && countInsert > 0) {
            apiResult.setCode(200);
            apiResult.setMessage("修改成功");
        } else {
            apiResult.setCode(506);
            apiResult.setMessage("修改失败");
        }

        return apiResult;
    }


}
